package es.udc.pfc.davidparedes.web.pages.user;

import java.util.Calendar;
import java.util.List;

import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SessionState;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;

import es.udc.pfc.davidparedes.model.store.Store;
import es.udc.pfc.davidparedes.model.storeservice.StoreService;
import es.udc.pfc.davidparedes.model.universe.Universe;
import es.udc.pfc.davidparedes.model.userprofile.UserProfile;
import es.udc.pfc.davidparedes.model.userservice.UserService;
import es.udc.pfc.davidparedes.model.userservice.VendorRowStatsDTO;
import es.udc.pfc.davidparedes.model.userservice.VendorUniverseStatsDTO;
import es.udc.pfc.davidparedes.model.util.GlobalNames;
import es.udc.pfc.davidparedes.model.util.InstanceNotFoundException;
import es.udc.pfc.davidparedes.model.vendor.Vendor;
import es.udc.pfc.davidparedes.web.services.AuthenticationPolicy;
import es.udc.pfc.davidparedes.web.services.AuthenticationPolicyType;
import es.udc.pfc.davidparedes.web.util.Alert;
import es.udc.pfc.davidparedes.web.util.UserSession;

@AuthenticationPolicy(AuthenticationPolicyType.MANAGER_OR_ABOVE)
public class DisplayVendorProfile {
	
	@Property
	private UserProfile userProfile;
	
	@Property
	private Vendor vendor;
	
	@Property
	private Store store;
	
	@Property
	private Universe universe;
	
	@Property
	private List<VendorUniverseStatsDTO> tasksStats;
	
	@Property
	private VendorUniverseStatsDTO uniStats;
	
	@Property
	private List<VendorRowStatsDTO> missionsStats;
	
	@Property
	private VendorRowStatsDTO missionRow;
	
	@Property
	private VendorRowStatsDTO taskRow;
	
	@Property
	private Long weekTotalMissions;
	
	@Property
	private Long monthTotalMissions;
	
	@Property
	private Long trimesterTotalMissions;
	
	@Property
	private Long weekTotalTasks;
	
	@Property
	private Long monthTotalTasks;
	
	@Property
	private Long trimesterTotalTasks;
	
	@Property
	private Long weekTotalHours;
	
	@Property
	private Long monthTotalHours;
	
	@Property
	private Long trimesterTotalHours;
	
	@Property
	private Integer monthlyMaxHours;
	
	@Property
	private Integer monthNotCompHours;
	
	@Property
	private Integer monthPercent;
	
	@Property
	private String monthColor;
	
	@Property
	private Integer trimesterMaxCompHours;
	
	@Property
	private Integer trimesterCompHours;
	
	@Property
	private Integer trimesterPercent;
	
	@Property
	private String trimesterColor;
	
	@Property
	private Alert baseAlert;
	
	@Property
	private Alert compAlert;
    
    @SessionState(create=false)
    private UserSession userSession;
    
    @Inject
    private UserService userService;
    
    @Inject
    private StoreService storeService;
    
    @Inject
    private Messages messages;
    
    @InjectPage
    private Home home;
   
    void onActivate(Long id) throws InstanceNotFoundException {
		userProfile = userService.findUserProfile(userSession.getUserProfileId());
		vendor = userService.findVendor(id);
		if (userProfile.getStore() != vendor.getStore()) {
			redirect();
		}
		store = vendor.getStore();
		universe = vendor.getUniverse();
		Long trimesterCompMillis = (long) 0;
		Long monthNotCompMillis = (long) 0;
		
		// Tasks
		tasksStats = userService.getVendorTasksStats(vendor.getUserProfileId());
		weekTotalTasks = (long) 0;
		monthTotalTasks = (long) 0;
		trimesterTotalTasks = (long) 0;
		for (VendorUniverseStatsDTO uni : tasksStats) {
			for (VendorRowStatsDTO row : uni.getRows()) {
				weekTotalTasks += row.getWeekMillis();
				monthTotalTasks += row.getMonthMillis();
				trimesterTotalTasks += row.getTrimesterMillis();
				if ((row.getTaskType()=='C') |  (row.getTaskType()=='H') | (row.getTaskType()=='D')) {
					trimesterCompMillis += row.getTrimesterMillis();
				} else {
					monthNotCompMillis += row.getMonthMillis();
				}
			}
		}
		
		// Missions
		missionsStats = userService.getVendorMissionsStats(vendor.getUserProfileId());
		weekTotalMissions = (long) 0;
		monthTotalMissions = (long) 0;
		trimesterTotalMissions = (long) 0;
		for (VendorRowStatsDTO row : missionsStats) {
			weekTotalMissions += row.getWeekMillis();
			monthTotalMissions += row.getMonthMillis();
			trimesterTotalMissions += row.getTrimesterMillis();
			if ((row.getTaskType()=='C') |  (row.getTaskType()=='H') | (row.getTaskType()=='D')) {
				trimesterCompMillis += row.getTrimesterMillis();
			} else {
				monthNotCompMillis += row.getMonthMillis();
			}
		}
		
		// Total
		weekTotalHours = weekTotalTasks + weekTotalMissions;
		monthTotalHours = monthTotalTasks + monthTotalMissions;
		trimesterTotalHours = trimesterTotalTasks + trimesterTotalMissions;
		
		// Time control
		Long HOUR_IN_MILLIS = (long) (1000*60*60);
		
		float numOfWeeksMonth = userService.numOfWeeksMonth();
		float numOfWeeksTrimester = userService.numOfWeeksTrimester();
		
		monthlyMaxHours = (int) (vendor.getBaseHours() * numOfWeeksMonth);
		monthNotCompHours = (int) (monthNotCompMillis/HOUR_IN_MILLIS);
		if (monthNotCompHours > monthlyMaxHours) {
			monthPercent = 100;
			monthColor="bar-danger";
			baseAlert = new Alert(GlobalNames.ALERT_DANGER, messages.get("baseHoursExceeded"),
					messages.get("baseHoursExceededText"));
		} else {
			if (!(monthlyMaxHours > 0)) {
				monthPercent = 0;
				monthColor="";
			} else {
				monthPercent = (monthNotCompHours * 100) / monthlyMaxHours;
				if (monthPercent==100) {
					monthColor="bar-success";
					baseAlert = new Alert(GlobalNames.ALERT_SUCCESS, messages.get("baseHoursAssigned"),
							messages.get("baseHoursAssignedText"));
				} else {
					monthColor="";
					baseAlert = new Alert(GlobalNames.ALERT_NORMAL, messages.get("baseHoursLeft"),
							messages.get("baseHoursLeftText"));
				}
			}
		}
		
		trimesterMaxCompHours = (int) ((vendor.getBaseHours() * 0.3) * numOfWeeksTrimester);
		trimesterCompHours = (int) (trimesterCompMillis/HOUR_IN_MILLIS);
		if (trimesterCompHours > trimesterMaxCompHours) {
			trimesterPercent = 100;
			trimesterColor="danger";
			compAlert = new Alert(GlobalNames.ALERT_DANGER, messages.get("compHoursExceeded"),
					messages.get("compHoursExceededText"));
		} else {
			if (!(trimesterMaxCompHours > 0)) {
				trimesterPercent = 0;
				trimesterColor="success";
			} else {
				trimesterPercent = (trimesterCompHours * 100) / trimesterMaxCompHours;
				if (trimesterPercent<50) {
					trimesterColor="success";
				} else {
					trimesterColor="warning";
				}
			}
		}
		
    }
    
    private Object redirect() {
    	return home;
    }
    
    public String formatDate(Calendar date) {
    	return Integer.toString(date.get(Calendar.DAY_OF_MONTH))
    		+ "/" + Integer.toString((date.get(Calendar.MONTH)+1))
    		+ "/" + Integer.toString(date.get(Calendar.YEAR));
    }
    
    public String formatTime(Long n) {
   		Integer h = (int) (n / (1000*60*60));
   		Integer m = (int) ((n % (1000*60*60)) / (1000*60));
   		String text = h + " " + messages.get("hours");
   		if (m > 0) {
   			text += ", " + m + " " + messages.get("minutes");
   		}
   		return text;
   	}
    
    public Boolean isNotEmpty(List<Object> l) {
   		if (l.size()>0) {
   			return true;
   		}
   		return false;
   	}
    
    public boolean isDirector() {
   		if (userSession.getUserType().equals(GlobalNames.USER_TYPE_DIRECTOR)){
   			return true;
   		}
        return false;
	}
}
